﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
using System;
using System.Collections.Generic;
using System.Text;

namespace Quickuse.Logging.EmailLogger
{
    /// <summary>
    /// EmailLoggerSettings
    /// </summary>
    internal class EmailLoggerSettings : IEmailLoggerSettings
    {
        private IConfiguration _configuration;
        private ILoggingConfiguration _loggingConfiguration;

        /// <summary>
        /// EmailLoggerSettings
        /// </summary>
        /// <param name="configuration">configuration</param>
        /// <param name="loggingConfiguration">loggingConfiguration</param>
        public EmailLoggerSettings(IConfiguration configuration, ILoggingConfiguration loggingConfiguration)
        {
            _configuration = configuration;
            _loggingConfiguration = loggingConfiguration;
            ChangeToken = _configuration.GetReloadToken();
        }

        /// <summary>
        /// ChangeToken
        /// </summary>
        public IChangeToken ChangeToken { get; set; }

        /// <summary>
        /// Reload
        /// </summary>
        /// <returns></returns>
        public IEmailLoggerSettings Reload()
        {
            ChangeToken = null;
            return new EmailLoggerSettings(_configuration, _loggingConfiguration);
        }

        /// <summary>
        /// 应用标识
        /// </summary>
        public string AppId => _configuration.GetAppId();

        /// <summary>
        /// ClusterSeq
        /// </summary>
        public string ClusterSeq => _configuration.GetClusterSeq();

        /// <summary>
        /// IncludeScopes (默认true)
        /// </summary>
        public bool IncludeScopes
        {
            get
            {
                var value = _configuration[$"Logging:{PublicConst.EmailLoggerName}:IncludeScopes"];
                if (string.IsNullOrEmpty(value))
                {
                    value = _loggingConfiguration.Configuration?.GetSection(PublicConst.EmailLoggerName)?["IncludeScopes"];
                }

                if (bool.TryParse(value, out var includeScopes))
                {
                    return includeScopes;
                }
                else
                {
                    return true;
                }
            }
        }

        /// <summary>
        /// 邮件服务器
        /// </summary>
        public string MailServer
        {
            get
            {
                var value = _configuration[$"Logging:{PublicConst.EmailLoggerName}:MailServer"];
                if (string.IsNullOrEmpty(value))
                {
                    value = _loggingConfiguration.Configuration?.GetSection($"{PublicConst.EmailLoggerName}")?["MailServer"];
                }
                return value;
            }
        }

        /// <summary>
        /// 发送邮件账号
        /// </summary>
        public string FromMail
        {
            get
            {
                var value = _configuration[$"Logging:{PublicConst.EmailLoggerName}:FromMail"];
                if (string.IsNullOrEmpty(value))
                {
                    value = _loggingConfiguration.Configuration?.GetSection($"{PublicConst.EmailLoggerName}")?["FromMail"];
                }

                return value;
            }
        }

        /// <summary>
        /// 账号
        /// </summary>
        public string MailAccount
        {
            get
            {
                var value = _configuration[$"Logging:{PublicConst.EmailLoggerName}:MailAccount"];
                if (string.IsNullOrEmpty(value))
                {
                    value = _loggingConfiguration.Configuration?.GetSection($"{PublicConst.EmailLoggerName}")?["MailAccount"];
                }

                return value;
            }
        }

        /// <summary>
        /// 密码
        /// </summary>
        public string MailPassword
        {
            get
            {
                var value = _configuration[$"Logging:{PublicConst.EmailLoggerName}:MailPassword"];
                if (string.IsNullOrEmpty(value))
                {
                    value = _loggingConfiguration.Configuration?.GetSection($"{PublicConst.EmailLoggerName}")?["MailPassword"];
                }

                return value;
            }
        }

        /// <summary>
        /// 接收邮件账号列表
        /// </summary>
        public string ToMails
        {
            get
            {
                var value = _configuration[$"Logging:{PublicConst.EmailLoggerName}:ToMails"];
                if (string.IsNullOrEmpty(value))
                {
                    value = _loggingConfiguration.Configuration?.GetSection($"{PublicConst.EmailLoggerName}")?["ToMails"];
                }

                return value;
            }
        }

        /// <summary>
        /// 邮件主题
        /// </summary>
        public string SubjectName
        {
            get
            {
                var value = _configuration[$"Logging:{PublicConst.EmailLoggerName}:SubjectName"];
                if (string.IsNullOrEmpty(value))
                {
                    value = _loggingConfiguration.Configuration?.GetSection($"{PublicConst.EmailLoggerName}")?["SubjectName"];
                }

                return value;
            }
        }

        /// <summary>
        /// Levels
        /// </summary>
        public List<LogLevel> Levels
        {
            get
            {
                var levels = new List<LogLevel>();

                var value = _configuration[$"Logging:{PublicConst.EmailLoggerName}:Levels"];
                if (string.IsNullOrEmpty(value))
                {
                    value = _loggingConfiguration.Configuration?.GetSection($"{PublicConst.EmailLoggerName}")?["Levels"];
                }

                if (string.IsNullOrEmpty(value))
                {
                    return levels;
                }

                var levelarray = value.Split(new string[] { ",", "，", ";", ";"," " }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var level in levelarray)
                {
                    if (Enum.TryParse(typeof(LogLevel), level, out var result))
                    {
                        levels.Add((LogLevel)result);
                    }
                }

                return levels;
            }
        }

        /// <summary>
        /// IsAsyn (默认 true)
        /// </summary>
        public bool IsAsyn
        {
            get
            {
                var value = _configuration[$"Logging:{PublicConst.EmailLoggerName}:IsAsyn"];
                if (string.IsNullOrEmpty(value))
                {
                    value = _loggingConfiguration.Configuration?.GetSection($"{PublicConst.EmailLoggerName}")?["IsAsyn"];
                }

                if (bool.TryParse(value, out var isasyn))
                {
                    return isasyn;
                }
                else
                {
                    return true;
                }
            }
        }

        /// <summary>
        /// 最大排队长度 (默认 10240)
        /// </summary>
        public int MaxQueuedLength
        {
            get
            {
                var value = _configuration[$"Logging:{PublicConst.EmailLoggerName}:MaxQueuedLength"];
                if (string.IsNullOrEmpty(value))
                {
                    value = _loggingConfiguration.Configuration?.GetSection($"{PublicConst.EmailLoggerName}")?["MaxQueuedLength"];
                }

                if (int.TryParse(value, out var maxqueuedlength))
                {
                    return maxqueuedlength;
                }

                return PublicConst.MaxQueuedLength;
            }
        }

        /// <summary>
        /// 获得/设置 实例销毁时日志任务等待时间 默认为 2 秒
        /// </summary>
        public TimeSpan TaskWaitTime
        {
            get
            {
                var value = _configuration["Logging:Email:TaskWaitTime"];
                if (string.IsNullOrEmpty(value))
                {
                    value = _loggingConfiguration.Configuration?.GetSection($"{PublicConst.EmailLoggerName}")?["TaskWaitTime"];
                }

                if (int.TryParse(value, out var taskwaitTime))
                {
                    return TimeSpan.FromSeconds(taskwaitTime);
                }

                return TimeSpan.FromSeconds(2);
            }
        }

        /// <summary>
        /// TryGetSwitch
        /// </summary>
        /// <param name="name">name</param>
        /// <param name="level">level</param>
        /// <returns></returns>
        public bool TryGetSwitch(string name, out LogLevel level)
        {
            var switches = _configuration.GetSection("LogLevel");
            if (switches == null)
            {
                level = LogLevel.None;
                return false;
            }

            var value = switches[name];
            if (string.IsNullOrEmpty(value))
            {
                level = LogLevel.None;
                return false;
            }
            else if (Enum.TryParse<LogLevel>(value, true, out level))
            {
                return true;
            }
            else
            {
                var message = $"Configuration value '{value}' for category '{name}' is not supported.";
                throw new InvalidOperationException(message);
            }
        }
    }
}
